home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / BORL_TIP / TI2000 / TI2677.ASC < prev    next >
Text File  |  1994-09-19  |  5KB  |  233 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.   PRODUCT  :  Pascal                                 NUMBER  :  2677
  8.   VERSION  :  All
  9.        OS  :  DOS
  10.      DATE  :  September 9, 1994                        PAGE  :  1/4
  11.  
  12.     TITLE  :  Trapping 8087 floating point exceptions in Pascal.
  13.  
  14.  
  15.  
  16.  
  17. (*
  18. This unit allows you to selectively handle floating point
  19. errors - such a operations on NANs or infinity numbers - 
  20. generated by the 8087 numeric coprocessor or emulation.  
  21. This unit basically implements Pascal versions of C's 
  22. _control87() and _stat87() functions and offers startup
  23. code for a user-defined int75h handler.  For complete 
  24. documentation on all of the constants in this unit, you
  25. should reference either the C documentation on _control87(),
  26. _stat87(), or signal(), or reference a 8087 programmer's guide.
  27. *) 
  28.  
  29.  
  30. unit Except87;
  31.  
  32. {
  33.   NOTES: This unit is intended only for use on machines with an
  34.          80286 processor or higher.
  35.  
  36.          If you intend to hook interrupt 75h while using this unit,
  37.          you should call Int75Startup as the first line in your
  38.          interrupt handler or very, very bad things will happen.
  39. }
  40.  
  41. {$IfNDef Windows}
  42.  
  43. {$N+,E+}
  44.  
  45. {$Else}
  46.  
  47. {$N+}
  48.  
  49. {$EndIf}
  50.  
  51. interface
  52.  
  53. const
  54.   { 387 Status Word format }
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.   PRODUCT  :  Pascal                                 NUMBER  :  2677
  68.   VERSION  :  All
  69.        OS  :  DOS
  70.      DATE  :  September 9, 1994                        PAGE  :  2/4
  71.  
  72.     TITLE  :  Trapping 8087 floating point exceptions in Pascal.
  73.  
  74.  
  75.  
  76.  
  77.   SW_INVALID      = $0001;  { Invalid operation            }
  78.   SW_DENORMAL     = $0002;  { Denormalized operand         }
  79.   SW_ZERODIVIDE   = $0004;  { Zero divide                  }
  80.   SW_OVERFLOW     = $0008;  { Overflow                     }
  81.   SW_UNDERFLOW    = $0010;  { Underflow                    }
  82.   SW_INEXACT      = $0020;  { Precision (Inexact result)   }
  83.   SW_STACKFAULT   = $0040;  { Stack fault                  }
  84.  
  85.   { 387 Control Word format }
  86.   MCW_EM              = $003f;  { interrupt Exception Masks}
  87.       EM_INVALID      = $0001;  {   invalid                }
  88.       EM_DENORMAL     = $0002;  {   denormal               }
  89.       EM_ZERODIVIDE   = $0004;  {   zero divide            }
  90.       EM_OVERFLOW     = $0008;  {   overflow               }
  91.       EM_UNDERFLOW    = $0010;  {   underflow              }
  92.       EM_INEXACT      = $0020;  {   inexact (precision)    }
  93.  
  94.   MCW_IC              = $1000;  { Infinity Control }
  95.       IC_AFFINE       = $1000;  {   affine         }
  96.       IC_PROJECTIVE   = $0000;  {   projective     }
  97.  
  98.   MCW_RC          = $0c00;  { Rounding Control     }
  99.       RC_CHOP     = $0c00;  {   chop               }
  100.       RC_UP       = $0800;  {   up                 }
  101.       RC_DOWN     = $0400;  {   down               }
  102.       RC_NEAR     = $0000;  {   near               }
  103.  
  104.   MCW_PC          = $0300;  { Precision Control    }
  105.       PC_24       = $0000;  {    24 bits           }
  106.       PC_53       = $0200;  {    53 bits           }
  107.       PC_64       = $0300;  {    64 bits           }
  108.  
  109. function Control87(New, Mask: Word): Word;
  110. function Status87: Word;
  111. procedure Int75Startup; far;
  112.  
  113. implementation
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.   PRODUCT  :  Pascal                                 NUMBER  :  2677
  128.   VERSION  :  All
  129.        OS  :  DOS
  130.      DATE  :  September 9, 1994                        PAGE  :  3/4
  131.  
  132.     TITLE  :  Trapping 8087 floating point exceptions in Pascal.
  133.  
  134.  
  135.  
  136.  
  137. procedure Int75Startup; assembler;
  138. asm   { this is the entry code for your int 75 handler }
  139.   xor al,   al                  { Clear BUSY latch}
  140.   out 0F0h, al
  141.   mov al,   20H                 { End-of-interrupt}
  142.   out 0A0h, al
  143.   out 20h,  al
  144. end;
  145.  
  146. function Control87(New, Mask: Word): Word; assembler;
  147. var
  148.   Control: Word;
  149. asm
  150.   fstcw    Control
  151.   mov  ax, New
  152.   mov  bx, Mask
  153.   and  ax, bx
  154.   not  bx
  155.   fwait
  156.   mov  dx, Control
  157.   and  dx, bx
  158.   mov  Control, ax
  159.   fldcw    Control
  160.   xchg ax, dx
  161. end;
  162.  
  163. function Status87: Word; assembler;
  164. var
  165.   Status: Word;
  166. asm
  167.   fstsw   Status
  168.   fwait
  169.   mov ax, Status
  170.   and ax, SW_INVALID+SW_ZERODIVIDE+SW_OVERFLOW+SW_UNDERFLOW+SW_INEXACT
  171. end;
  172.  
  173. end.
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.   PRODUCT  :  Pascal                                 NUMBER  :  2677
  188.   VERSION  :  All
  189.        OS  :  DOS
  190.      DATE  :  September 9, 1994                        PAGE  :  4/4
  191.  
  192.     TITLE  :  Trapping 8087 floating point exceptions in Pascal.
  193.  
  194.  
  195.  
  196.  
  197. (********  This is a test program for the Except87 unit *******)
  198.  
  199. program TestFP;
  200.  
  201. {$N+}
  202.  
  203. uses Except87, DOS;
  204.  
  205. var
  206.   f: single;
  207.   p: pointer;
  208.   i: word;
  209.  
  210. procedure Int75Handler; interrupt;
  211. begin
  212.   Int75Startup;
  213.   i := 1;
  214. end;
  215.  
  216. begin
  217.   i := 0;
  218.   Control87(0, MCW_EM);
  219.   GetIntVec($75, p);
  220.   SetIntVec($75, @Int75Handler);
  221.   f := 99999999999.99;
  222.   f := f / 0.0;
  223.   writeln('Coprocessor status: ', status87);
  224.   SetIntVec($75, p);
  225.   writeln('Did int75 fire?: ', i);
  226. end.
  227.  
  228.  
  229. DISCLAIMER: You have the right to use this technical information
  230. subject to the terms of the No-Nonsense License Statement that
  231. you received with the Borland product to which this information
  232. pertains.
  233.